package cc.rengu.igas.share.core.service.channel.ncqs;

import cc.rengu.igas.channel.ncqs.common.enums.RespCodeEnum;
import cc.rengu.igas.channel.ncqs.facade.base.Header;
import cc.rengu.igas.channel.ncqs.facade.bean.OriTrxInfo;
import cc.rengu.igas.channel.ncqs.facade.enums.NcqsBizTypeEnum;
import cc.rengu.igas.channel.ncqs.facade.request.NcqsAgreePaySignWithSmsAcqRequest;
import cc.rengu.igas.channel.ncqs.facade.response.NcqsAgreePaySignWithSmsAcqResponse;
import cc.rengu.igas.channel.ncqs.facade.result.Result;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.igas.share.common.constant.ShareServiceConstant;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.oltp.service.base.ChannelBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.DstChannelCfgMapper;
import cc.rengu.oltp.service.common.dao.impl.DstChannelCfgMapperImpl;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.DstChannelCfg;
import cc.rengu.oltp.service.common.entity.PayOrderInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.enums.ChannelCallModeEnum;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.model.TxnInfo;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.GlobalTransUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.List;

/**
 * NCQS协议支付签约触发短信
 * Created by lzl on 2021/4/23 11:08
 */
public class NcqsAgreePaySignWithSmsAcqService extends ChannelBaseService {
    @Override
    public Object callPreProc(TxnInfo txnInfo, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        Header ncqsHeader = new Header();
        ncqsHeader.setInstId(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID));
        ncqsHeader.setChanlId(channelCallCfg.getMsgSrcId());
        ncqsHeader.setSrcSysId(AppParamConstant.SYS_ID);
        ncqsHeader.setBizType(AppParamConstant.DEFAULT_BIZ_TYPE);
        ncqsHeader.setVersion(ShareParamConstant.DUBBO_VSERSION);
        ncqsHeader.setTxnNum(channelCallCfg.getCallChannelTxn());
        ncqsHeader.setTraceNo(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM) + channelCallCfg.getCallIndex());
        ncqsHeader.setTransTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_TIME));
        ncqsHeader.setTransDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TRANS_DATE));
        NcqsAgreePaySignWithSmsAcqRequest ncqsAgreePaySignWithSmsAcqRequest = new NcqsAgreePaySignWithSmsAcqRequest();
        ConvertUtil.convertOutput(ncqsAgreePaySignWithSmsAcqRequest);
        ncqsAgreePaySignWithSmsAcqRequest.setHeader(ncqsHeader);
        DstChannelCfgMapper dstChannelCfgMapper = new DstChannelCfgMapperImpl();
        List<DstChannelCfg> dstChannelCfgList = dstChannelCfgMapper.selectDstChannelCfgBydstChannelId(ncqsHeader.getInstId(), ChannelEnum.NCQS.getChannelType());
        if (dstChannelCfgList.isEmpty() || StringUtil.isEmptyOrNull(dstChannelCfgList.get(0).getOtherConfParam())) {
            rglog.info("不存在可用的全渠道TOKENID和TOKENTYPE");
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(dstChannelCfgList.get(0).getOtherConfParam());
        if (orderInfo != null) {
            ncqsAgreePaySignWithSmsAcqRequest.setCupsInstCode(jsonObject.getString("cupsInstId"));
            ncqsAgreePaySignWithSmsAcqRequest.setBusiType(NcqsBizTypeEnum.NCQS_100003.getBizTypeCode());
            OriTrxInfo oriTrxInfo = new OriTrxInfo();
            oriTrxInfo.setOriSettleKey(orderInfo.getPayOrderInfoList().get(0).getChannelReconKey());
            oriTrxInfo.setOriOrderId(orderInfo.getPayOrderInfoList().get(0).getSysSeqNum());
            oriTrxInfo.setOriBusiType(NcqsBizTypeEnum.NCQS_100003.getBizTypeCode());
            oriTrxInfo.setOriTransType("1101");
        } else {
            SysParamService sysParamService = new SysParamServiceImpl();
            SysParam ncqsInstCodeParam = sysParamService.getSysParamInfo(ncqsHeader.getInstId(), "OPMS_SYS_PARAM", "NCQS_INST_CODE");
            if (null == ncqsInstCodeParam || AppParamConstant.NO.equals(ncqsInstCodeParam.getParamStatus())) {
                rglog.error("机构为设置无卡快捷银联机构号，instId:<{}>", ncqsHeader.getInstId());
                throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
            }
            ncqsAgreePaySignWithSmsAcqRequest.setCupsMchntNo(jsonObject.getString("cupsMchntNo"));
            ncqsAgreePaySignWithSmsAcqRequest.setMchntType(jsonObject.getString("mchntType"));
            ncqsAgreePaySignWithSmsAcqRequest.setMchntName("");
            ncqsAgreePaySignWithSmsAcqRequest.setBusiType(NcqsBizTypeEnum.NCQS_ACCT_SERVICE.getBizTypeCode());
            ncqsAgreePaySignWithSmsAcqRequest.setBusiFuncType("111011");
            ncqsAgreePaySignWithSmsAcqRequest.setProductType("00000000");
            ncqsAgreePaySignWithSmsAcqRequest.setPayAcctName(xmlTreeUtil.getXmlTreeStringValue("cardHoldName"));
            ncqsAgreePaySignWithSmsAcqRequest.setPayAcctNo(xmlTreeUtil.getXmlTreeStringValue("acctNo"));
            ncqsAgreePaySignWithSmsAcqRequest.setCorpName("");
            ncqsAgreePaySignWithSmsAcqRequest.setLicenceNo("");
            ncqsAgreePaySignWithSmsAcqRequest.setCupsInstCode(ncqsInstCodeParam.getParamValue());
        }
        rglog.debug("NCQS协议支付签约触发短信请求:<{}>", JSON.toJSONString(ncqsAgreePaySignWithSmsAcqRequest));

        return ncqsAgreePaySignWithSmsAcqRequest;
    }

    @Override
    public PayOrderInfo generatePayOrderInfo(ChannelCallCfg channelCallCfg, OrderInfo orderInfo, Object request) throws Exception {
        //此交易不登记支付订单
        return null;
    }

    @Override
    public Object callProc(ChannelCallCfg channelCallCfg, Object request) throws Exception {
        NcqsAgreePaySignWithSmsAcqRequest ncqsAgreePaySignWithSmsAcqRequest = (NcqsAgreePaySignWithSmsAcqRequest) request;
        /* Step1：调用接口，获取结果 */
        Result<NcqsAgreePaySignWithSmsAcqResponse> callResult;
        DubboService dubboService = new DubboServiceImpl();
        if (AppParamConstant.YES.equals(channelCallCfg.getSyncCallFlag())) {
            /* Step1.1：异步调用 */
            int iReturnCode;
            int callTimes = 0 == channelCallCfg.getSyncQueryRepeatNum() ? 1 : channelCallCfg.getSyncQueryRepeatNum();
            int gatTime = channelCallCfg.getSyncQueryRepeatTime();
            int gatType = StringUtil.isEmptyOrNull(channelCallCfg.getSyncQueryGapType()) ? 0 : Integer.parseInt(channelCallCfg.getSyncQueryGapType());
            if (ChannelCallModeEnum.LOCAL.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.1.1：异步应用内调用 */
                Class clasz = Class.forName(ShareServiceConstant.NCQS_SERVICE_INNER_PATH);
                iReturnCode = dubboService.asynCallDubboInnerMethod(clasz, ShareServiceConstant.NCQS_AGREE_PAY_SIGN_WITH_SMS_METHOD, ncqsAgreePaySignWithSmsAcqRequest, channelCallCfg.getSyncResultServiceName(), callTimes, gatType, gatTime);
            } else if (ChannelCallModeEnum.REMOTE.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.1.2：异步远程调用 */
                iReturnCode = dubboService.asynCallDubboService(ShareServiceConstant.NCQS_SERVICE, ShareServiceConstant.NCQS_AGREE_PAY_SIGN_WITH_SMS_METHOD, ncqsAgreePaySignWithSmsAcqRequest, channelCallCfg.getSyncResultServiceName(), callTimes, gatType, gatTime);
            } else {
                rglog.error("不支持的通道服务调用方式:{}，交易拒绝!", channelCallCfg.getChannelCallMode());
                throw new BizException(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR);
            }
            if (0 == iReturnCode) {
                return new BizResponse<>(OltpRpcdEnum.TRANS_SUCCESS.getRespCode(), OltpRpcdEnum.TRANS_SUCCESS.getRespDesc());
            } else {
                return new BizResponse<>(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespCode(), OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR.getRespDesc());
            }
        } else {
            /* Step1.2：同步调用 */
            if (ChannelCallModeEnum.LOCAL.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.2.1：同步应用内调用 */
                Class clasz = Class.forName(ShareServiceConstant.NCQS_SERVICE_INNER_PATH);
                callResult = (Result<NcqsAgreePaySignWithSmsAcqResponse>) dubboService.callDubboInnerMethod(clasz, ShareServiceConstant.NCQS_AGREE_PAY_SIGN_WITH_SMS_METHOD, ncqsAgreePaySignWithSmsAcqRequest);
            } else if (ChannelCallModeEnum.REMOTE.getMode().equals(channelCallCfg.getChannelCallMode())) {
                /* Step1.2.2：同步远程调用 */
                callResult = (Result<NcqsAgreePaySignWithSmsAcqResponse>) dubboService.callDubboService(ShareServiceConstant.NCQS_SERVICE, ShareServiceConstant.NCQS_AGREE_PAY_SIGN_WITH_SMS_METHOD, ncqsAgreePaySignWithSmsAcqRequest);
            } else {
                rglog.error("不支持的通道服务调用方式:{}，交易拒绝!", channelCallCfg.getChannelCallMode());
                throw new BizException(OltpRpcdEnum.CALL_BIZ_SERVICE_ERROR);
            }
        }
        return callResult;
    }

    @Override
    public Object querySyncCallResult(PayOrderInfo payOrderInfo, Object request) {
        return null;
    }

    @Override
    public OrderInfo callResultOrderProc(OrderInfo orderInfo, String payOrderIndex, TransStatusEnum transStatusEnum, Object response) {
        //此交易不登记订单
        return null;
    }
}
